#coding=utf-8
#!/bin/env python
# 参考地址:
# ui 命令 pyuic4 -o t_ui.py t.ui
from PyQt4.QtGui import * 
from PyQt4.QtCore import *
from PIL import Image 
import sys, t_ui, os, os.path, threading,shutil
import win32event, pywintypes, win32api
import traceback
import ConfigParser

reload(sys)
sys.setdefaultencoding( "utf-8" )

class MainWindow(QDialog, t_ui.Ui_Dialog):

	#信号槽
	setPBarSignal = pyqtSignal(int)
	setFinishSignal = pyqtSignal()
	setErrorSignal = pyqtSignal(str)

	def __init__(self, parent=None):

		super(MainWindow, self).__init__(parent)
        	self.setupUi(self)
        	self.Init()
        	self.Listen()

        #init-初始化
        def Init(self):
        	self.progressBar.setValue(0)
        	self.VersionLable.setText(u"版本:1.2.1") 
        	self.SourceGetPath = ""
        	self.targetSizeEdit.setText(u"40")

    		_Config = Config("config.ini")
    		path = _Config.get('Common','path')
    		if(path):
    			self.SourcePathEdit.setText(path)
    			self.SourceGetPath = path

        	global loglistWidget
        	loglistWidget = self.loglistWidget
        	_log("初始化成功")

        #监听事件	
    	def Listen(self):
    		self.SourceGetDirBtn.clicked.connect(lambda: self.OnClickGetDir(self.SourcePathEdit))
    		self.Working.clicked.connect(self.OnClickStartWorking)

    	#选择文件夹事件
    	def OnClickGetDir(self, object):
    		self.SourceGetPath = QFileDialog.getExistingDirectory(self , u'请选择文件夹')
    		if(self.SourceGetPath != ""):
    			object.setText(self.SourceGetPath)

    	    	#保存配置文件
    	    	_Config = Config("config.ini")
    	    	_Config.set('Common','path',self.SourceGetPath)
    	
    	#监听事件
    	def OnClickStartWorking(self):
    		if(self.SourceGetPath == ""):
    			QMessageBox.information( self, u"提示",  u"请选择文件夹", QMessageBox.Yes)
    			return

    		self.targetSize = str(self.targetSizeEdit.text())
    		if(self.targetSize.isdigit() == False):
    			QMessageBox.information( self, u"提示",  u"请填写正确的图片大小", QMessageBox.Yes)
    			return
    		global targetSize
    		targetSize = int(self.targetSize) * 1024 #还原kb	

    		#信号槽
    		self.setPBarSignal.connect(self.setValueProgressBar)
    		self.setFinishSignal.connect(self.setFinish)
    		self.setErrorSignal.connect(self.setError)

          	self.ThreadClass = ThreadClass(self)
          	self.ThreadClass.daemon = True
          	self.ThreadClass.start()
 			
 		#信号槽
        def setValueProgressBar(self,num):
    		self.progressBar.setValue(num)

    	def setFinish(self):
    		_log("操作成功")
    		QMessageBox.information(self, u"提示",  u"操作成功", QMessageBox.Yes)

    	def setError(self,errortxt):
    		QMessageBox.critical(self, u"提示",  errortxt, QMessageBox.Yes)

#日志 
def _log(txt):
	global loglistWidget
	loglistWidget.addItem(unicode(txt,"UTF-8"))
	index = loglistWidget.currentRow() 

#错误日志
def trace_back():  
    try:  
        return traceback.print_exc()  
    except:  
        return ''

#线程
class ThreadClass(threading.Thread):

	def __init__(self, object):
		threading.Thread.__init__(self)
		self.object = object
		#初始化数据
		self.count   =  0
		self.now     =  0 
		self.total   =  100
		self.PathArr =  []
		self.TargetArr = []

	def run(self):

		_log("开始线程")
		SourcePath = os.path.normpath( str(self.object.SourcePathEdit.text()) )		
		Targetpath = ImageCompress().GetTarGetPath(SourcePath)
		if(os.path.isdir(Targetpath) == True):shutil.rmtree(Targetpath)

		#计算文件夹中遍历出来
		for parent,dirnames,filenames in os.walk(SourcePath):
			self.PathArr.append(filenames)

		for value in self.PathArr[0]:
			if( '.jpg' in value):
				self.TargetArr.append(value)
				self.count += 1

		#计算每份数量		
		each = self.total / self.count
		self.object.setPBarSignal.emit(0)

		try:

			#开始处理
			for filename in self.TargetArr:
				self.now += each
				print self.now
				_log( "当前进度"+str(self.now)+"%")
				ImageCompress().ImageCompress(SourcePath, filename, SourcePath,100)
				self.object.setPBarSignal.emit(self.now)
				print "-------------------------------------"
				_log("-------------------------------------")

			#处理结束
			self.object.setPBarSignal.emit(100)
			self.object.setFinishSignal.emit()

		except: 
			self.object.setPBarSignal.emit(100) 
    		print trace_back() 	
		
class ImageCompress():
	
	def __init__(self):
		global targetSize
		self.targetSize = targetSize #压缩大小
		self._quality = 2 #递归试探
		self._out = u"压缩"
	
	def GetTarGetPath(self, targetpath):#新地址
		targetPath = targetpath + "\\" + self._out 
		return targetPath

	def ImageCompress(self, parent, filename, targetpath, quality=100):
		targetPath = self.GetTarGetPath(targetpath)
		if(os.path.isdir(targetPath) == False):os.mkdir(targetPath) #判断目录是否存在，不存在则创建
		target = targetPath + "\\" + filename
		if(quality == 100):
			quality = self.CompactionSize( int(os.path.getsize(os.path.join(parent, filename))) )
			print u"比例"+str(quality)

		SourceImage = Image.open(os.path.join(parent, filename)) #图片压缩
		SourceImage.save(target, quality=quality)
		print target,os.path.getsize(target)
		_log(str(target)+" "+str(os.path.getsize(target)))
		if(os.path.getsize(target) > self.targetSize):
			self.ImageCompress(parent, filename, targetpath, quality-self._quality)

	#计算当前比例
	def CompactionSize(self,nowSize):
		return int( round ( (self.targetSize / float(nowSize)) , 2) * 100 )

#操作INI
class Config:  
    def __init__(self, path):  
        self.path = path  
        self.cf = ConfigParser.ConfigParser()  
        self.cf.read(self.path)
    def get(self, field, key):  
        result = ""  
        try:  
            result = self.cf.get(field, key)  
        except:  
            result = ""
        return result  
    def set(self, field, key, value):  
        try:  
            self.cf.set(field, key, value)
            self.cf.write(open(config_ini_name,'r+')) 
        except:  
            return False  
        return True  


#执行方法启动
ERROR_ALREADY_EXISTS = 183
sz_mutex = "test_mutex"
hmutex = win32event.CreateMutex(None, pywintypes.FALSE,sz_mutex)
if (win32api.GetLastError() == ERROR_ALREADY_EXISTS):
    print "No Allow Open"
    exit(0)
else:

	global config_ini
	global config_ini_name
	config_ini_name = "config.ini"
	config_ini=ConfigParser.ConfigParser()
	status = config_ini.read(config_ini_name)
	if(status):
		pass
	else:
		config_ini_path = open(config_ini_name,'w+')
		config_ini.read(config_ini_name)
		config_ini.add_section('Common')
		config_ini.set('Common','PATH','')
		config_ini.write(config_ini_path)
		config_ini_path.close()

	app = QApplication(sys.argv)
	dialog = MainWindow()
	dialog.setWindowIcon(QIcon('./favicon.ico'))
	dialog.show()
	app.exec_()